package common

import (
	"bytes"
	"fmt"
	"git.supremind.info/product/box/vehicle/config"
	"git.supremind.info/product/box/vehicle/global"
	"github.com/gin-gonic/gin"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/rifflock/lfshook"
	log "github.com/sirupsen/logrus"
	"path"
	"time"
)

//日志输出全局变量
var Logger = log.New()

func InitLogger(appConfig *config.AppSettings) {
	//设置日志级别
	Logger.SetLevel(log.DebugLevel)

	//打印日志方法
	Logger.ReportCaller = true

	var fileName = appConfig.LogFileName + appConfig.LogFileExt
	// 日志文件地址
	fileName = path.Join(global.LogSavePath, fileName)

	writer1, err := rotatelogs.New(
		fileName+"%Y%m%d%H%M.log",
		rotatelogs.WithLinkName(fileName),                        //软连接，只想最新日志文件
		rotatelogs.WithMaxAge(7*24*time.Hour),                    //最大保存时间
		rotatelogs.WithRotationTime(time.Duration(24)*time.Hour), //日志分割时间间隔
	)

	if err != nil {
		Logger.Errorf("创建日志文件失败， %s, ", err.Error())
	}

	lfHook := lfshook.NewHook(lfshook.WriterMap{
		log.DebugLevel: writer1, // 为不同级别设置不同的输出目的
		log.InfoLevel:  writer1,
		log.WarnLevel:  writer1,
		log.ErrorLevel: writer1,
		log.FatalLevel: writer1,
		log.PanicLevel: writer1,
	}, &BaseFormatter{}) //日志输出格式

	Logger.AddHook(lfHook)
}

type BaseFormatter struct {
}

func (m *BaseFormatter) Format(entry *log.Entry) ([]byte, error) {
	var b *bytes.Buffer
	if entry.Buffer != nil {
		b = entry.Buffer
	} else {
		b = &bytes.Buffer{}
	}

	timestamp := entry.Time.Format("2006-01-02 15:04:05")
	var newLog string

	var funcVal, fileVal string
	if entry.HasCaller() {
		if entry.Caller.Function != "" {
			funcVal = entry.Caller.Function
		}
		fileVal = fmt.Sprintf("%s:line %d", path.Base(entry.Caller.File), entry.Caller.Line)
		newLog = fmt.Sprintf("[%s] [%s] [%s]-[%s] %s\n", timestamp, entry.Level, fileVal, funcVal, entry.Message)
	} else {
		newLog = fmt.Sprintf("[%s] [%s] %s\n", timestamp, entry.Level, entry.Message)
	}

	b.WriteString(newLog)
	return b.Bytes(), nil
}

func LogerMiddleware() gin.HandlerFunc {

	return func(c *gin.Context) {
		//开始时间
		startTime := time.Now()
		//处理请求
		c.Next()
		//结束时间
		endTime := time.Now()
		// 执行时间
		latencyTime := endTime.Sub(startTime)
		//请求方式
		reqMethod := c.Request.Method
		//请求路由
		reqUrl := c.Request.RequestURI
		//状态码
		statusCode := c.Writer.Status()
		//请求ip
		clientIP := c.ClientIP()

		// 日志格式
		Logger.WithFields(log.Fields{
			"status_code":  statusCode,
			"latency_time": latencyTime,
			"client_ip":    clientIP,
			"req_method":   reqMethod,
			"req_uri":      reqUrl,
		}).Infof("status_code：%d, latency_time: %s, client_ip: %s, req_method: %s, req_uri: %s", statusCode, latencyTime, clientIP, reqMethod, reqUrl)
	}
}
